package com.bt.framework.ext

import android.R
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
import org.json.JSONObject

/**
 *@author:hxm
 *@date: 2025/6/22 22:25
 *@version:
 *@description:GSON扩展
 */

/**
 * JsonObject创建
 */
fun gsonJsonObjectOf(vararg args : Pair<String, Any?>) = JsonObject().append(*args)

/**
 * JsonObject 添加字段
 */
fun JsonObject.append(vararg args : Pair<String, Any?>) : JsonObject{
    args.forEach { (name, value)->
        value?.let {
            when(it){
                is String-> append(name, it)
                is Number-> append(name, it)
                is Boolean-> append(name, it)
                is Char-> append(name, it)
                is JsonElement -> append(name, it)
                else-> append(name, it.toString())
            }
        }
    }
    return this
}

/**
 * JsonObject 添加字段
 */
fun JsonObject.append(other : JsonObject?) : JsonObject{
    other?.entrySet()?.forEach {(name, value)->
        append(name, value)
    }
    return this
}

/**
 * Json字符转字符串
 */
fun JsonObject.append(name : String, value : String?) : JsonObject{
    value?.let { addProperty(name, value) }
    return this
}

/**
 * Json字符转数字
 */
fun JsonObject.append(name : String, value : Number?) : JsonObject{
    value?.let { addProperty(name, value) }
    return this
}

/**
 * Json字符转Boolean
 */
fun JsonObject.append(name : String, value : Boolean?) : JsonObject{
    value?.let { addProperty(name, value) }
    return this
}

/**
 * Json字符串转JsonObject
 */
fun JsonObject.append(name : String, value : Char?) : JsonObject{
    value?.let { addProperty(name, value) }
    return this
}

/**
 * JsonElement转JsonObject
 */
fun JsonObject.append(name : String, value : JsonElement?) : JsonObject{
    value?.let { add(name, value) }
    return this
}

/**
 * JsonObject 添加字段
 */
operator fun JsonObject?.plus(other : JsonObject?) : JsonObject = gsonJsonObjectOf().also {
    it.append(this).append(other)
}

/**
 * Json字符串转JsonObject
 */
fun String.toJsonObject() : JsonObject?{
    return toJsonElement()?.asJsonObject
}

/**
 * Json字符串转JsonElement
 */
fun String.toJsonElement() : JsonElement?{
   if (!isJSONValid()) return null
    return JsonParser.parseString(this)
}

/**
 * Json字符串转PrettyJson
 */
val String.PrettyJson : String
    get(){
        if (isJSONValid()) return ""
        return JsonParser.parseString(this).toPrettyJson()
    }

/**
 * JsonElement 转 Bean
 */
inline fun <reified T> JsonElement.asBean() : T?{
    return if (isJsonObject) toBean() else null
}

/**
 * 是否为JSON字符串
 */
fun String.isJSONValid() : Boolean{
    try {
        JSONObject(this)
    }catch (e : Exception){
      try {
          JSONArray(this)
      }catch (e : Exception){
          return false
      }
    }
    return true
}


/**
 * 将Json字符串转换成Bean对象
 */
inline fun <reified T> JsonElement.toBeanOrNull(): T? = runCatching {
    toBean<T>()
}.getOrNull()

/**
 * 获取JsonObject，为NULL则返回NULL
 */
val JsonElement.asJsonObjectOrNull : JsonObject? get() = runCatching { asJsonObject }.getOrNull()

/**
 * 获取JsonArray，为NULL则返回NULL
 */
val JsonElement.asJsonArrayOrNull : JsonArray? get() = runCatching { asJsonArray }.getOrNull()

/**
 * 获取字符串，为NULL则返回NULL
 */
val JsonElement.asStringOrNull : String? get() = runCatching { asString }.getOrNull()

/**
 * 获取字符串，为NULL则返回空字符串
 */
val JsonElement.asStringOrEmpty : String get() = runCatching { asString }.getOrElse { "" }

/**
 * 转换为Int值或NULL
 */
val JsonElement.asIntOrNull : Int? get() = runCatching { asInt }.getOrNull()

/**
 * 转换为Boolean值或NULL
 */
val JsonElement.asBooleanOrNull : Boolean? get() = runCatching { asBoolean }.getOrNull()

/**
 * 将Bean对象转成[JsonObject]
 */
inline fun <reified T> T.toJsonObject(includeNulls: Boolean = true): JsonObject {
    return gson(includeNulls).toJsonTree(this, object : TypeToken<T>() {}.type).asJsonObject
}

private val GSON by lazy {
    GsonBuilder().create()
}

private val GSON_NO_NULLS by lazy {
    GsonBuilder().serializeNulls().create()
}

private val GSON_PRETTY by lazy {
    GsonBuilder().setPrettyPrinting().create()
}

/**
 * 有些json窜有引号，去除
 */
fun String.parseJson() = JsonParser.parseString(this)

/**
 * 将Bean对象转换成json字符串
 *
 * @receiver 任意Bean对象
 * @param includeNulls 是否包含值为空的字段（默认包含）
 * @return 转换后的json字符串
 */
fun Any.toJson(includeNulls: Boolean = true): String {
    return gson(includeNulls).toJson(this)
}

/**
 * 将Bean对象转换成可读性高的json字符串
 *
 * @receiver 任意Bean对象
 * @return 转换后的json字符串
 */
fun Any.toPrettyJson(): String {
    return GSON_PRETTY.toJson(this)
}

/**
 * 将json字符串转换成目标Bean对象
 *
 * @receiver json字符串
 * @param includeNulls 是否包含值为空的字段（默认包含）
 * @return 转换后的Bean对象
 */
inline fun <reified T> String.toBean(includeNulls: Boolean = true): T {
    return gson(includeNulls).fromJson(this, object : TypeToken<T>() {}.type)
}

inline fun <reified T> String.toBeanOrNull(includeNulls: Boolean = true): T? = runCatching {
    toBean<T>()
}.onFailure { it.printStackTrace() }.getOrNull()

/**
 * 将json字符串转换成目标Bean对象
 *
 * @receiver json元素
 * @param includeNulls 是否包含值为空的字段（默认包含）
 * @return 转换后的Bean对象
 */
inline fun <reified T> JsonElement.toBean(includeNulls: Boolean = true): T? {
    return gson(includeNulls).fromJson(this, object : TypeToken<T>() {}.type)
}

/**
 * Gson
 */
fun gson(includeNulls: Boolean): Gson = if (includeNulls) GSON else GSON_NO_NULLS